package com.bootdo.hjh.service.impl;

import com.bootdo.common.service.DistConfigValueService;
import com.bootdo.common.utils.PointTradeType;
import com.bootdo.common.utils.StringUtils;
import com.bootdo.hjh.dao.CashPointsDOMapper;
import com.bootdo.hjh.dao.OrderDOMapper;
import com.bootdo.hjh.dao.ProductDOMapper;
import com.bootdo.hjh.dao.UserAddressMapper;
import com.bootdo.hjh.dao.WithdrawDOMapper;
import com.bootdo.hjh.domain.CashPointsDO;
import com.bootdo.hjh.domain.OrderDO;
import com.bootdo.hjh.domain.OrderDOExample;
import com.bootdo.hjh.domain.ProductDO;
import com.bootdo.hjh.domain.ProductType;
import com.bootdo.hjh.domain.UserAddress;
import com.bootdo.hjh.domain.WithdrawDO;
import com.bootdo.hjh.ex.BizException;
import com.bootdo.hjh.ex.ThrowUtils;
import com.bootdo.hjh.service.OrderService;
import com.bootdo.hjh.service.PointsService;
import com.bootdo.shop.domain.OrderInfo;
import com.bootdo.shop.service.ShopOrderService;
import com.bootdo.system.dao.UserDao;
import com.bootdo.system.domain.UserDO;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service
@Transactional
public class OrderServiceImpl implements OrderService{


	@Autowired OrderDOMapper orderDOMapper;

	@Autowired ProductDOMapper productDOMapper;

	@Autowired UserDao userDao;

	@Autowired UserAddressMapper userAddressMapper;

	@Autowired
	private PointsService pointsService;

	@Autowired
	private WithdrawDOMapper withdrawDOMapper;

	@Autowired
	private CashPointsDOMapper cashPointsDOMapper;

	@Autowired
	private ShopOrderService shopOrderService;

	/**
	 * 配置服务
	 */
	@Autowired
	private DistConfigValueService distConfigValueService;

	@Override
	public Integer createOrder(Long createUserId,Long userId, Integer productId,Integer quantity,
							   Integer userAddressId, Long frUserId) {
		//查询产品是否存在
		ProductDO productDO = productDOMapper.selectByPrimaryKey(productId);
		if(null == productDO) {
			throw new RuntimeException("产品不存在");
		}
		UserDO user = userDao.get(userId);
		if(null == user) {
			throw new RuntimeException("用户不存在");
		}
		UserAddress userAddress = userAddressMapper.getUserAddressById(userAddressId);
		OrderDO order = new OrderDO();
		//订单号
		String orderNo = StringUtils.generateOrderNO("");
		order.setOrderNo(orderNo);
		//订单标题
		byte defaultStatus = 0;
		order.setOrderStatus(defaultStatus);
		order.setOrderTitle(productDO.getName());
		order.setCreateUserId(createUserId);//直推人
		order.setCreateTime(new Date());
		order.setOrderTitle(productDO.getName());
		order.setUserId(userId);
		order.setProductId(productId);
		order.setQuantity(quantity);//购买数量
		order.setSalePrice(productDO.getPrice());//单价
		order.setAmount(productDO.getPrice() * quantity); //总金额
		order.setProvince(userAddress.getProvince());
		order.setCity(userAddress.getCity());
		order.setDistrict(userAddress.getDistrict());
		order.setPostcode(userAddress.getPostcode());
		order.setAddress(userAddress.getAddress());
		order.setTel(userAddress.getTel());
		order.setMobile(userAddress.getMobile());
		order.setReceiver(userAddress.getName());
		order.setFrUserId(frUserId);
		//过期时间
		order.setExpirationTime(DateTime.now().plusDays(10).toDate());
		orderDOMapper.insertSelective(order);
		return null;
	}

	/**
	 * 补货订单
	 *
	 * @param createUserId 补货申请者
	 * @param frUserId 上级代理
	 * @param quantity 补货数量
	 * @return
	 */
	public Integer createBuhuoOrder(Long createUserId, Long frUserId, int quantity, int type) {
		//查询产品是否存在
		UserDO me = userDao.get(createUserId);
		if(null == me) {
			throw new BizException("用户不存在", 10002);
		}

		long price = getPrice(createUserId, type);
		int productId = ProductType.getByValue(type).getProductId();

		UserAddress userAddress = userAddressMapper.getUserAddressDefault(createUserId);
		if (userAddress == null) {
			List<UserAddress> userAddressForAll = userAddressMapper.getUserAddressForAll(createUserId);
			userAddress = userAddressForAll.get(0);
		}
		OrderDO order = new OrderDO();
		//订单号
		String orderNo = StringUtils.generateOrderNO("B");
		order.setOrderNo(orderNo);
		//订单标题
		byte defaultStatus = 0;
		order.setOrderStatus(defaultStatus);
		order.setOrderTitle("会员补货");
		order.setCreateUserId(createUserId);//直推人
		order.setCreateTime(new Date());
		order.setUserId(createUserId);
		order.setProductId(productId);
		order.setQuantity(quantity);//购买数量
		order.setSalePrice((int) price);//单价
		order.setAmount(((int) price) * quantity); //总金额
		order.setProvince(userAddress.getProvince());
		order.setCity(userAddress.getCity());
		order.setDistrict(userAddress.getDistrict());
		order.setPostcode(userAddress.getPostcode());
		order.setAddress(userAddress.getAddress());
		order.setTel(userAddress.getTel());
		order.setMobile(userAddress.getMobile());
		order.setReceiver(userAddress.getName());
		order.setFrUserId(frUserId);
		//过期时间
		order.setExpirationTime(DateTime.now().plusDays(10).toDate());
		orderDOMapper.insertSelective(order);
		return order.getId();
	}

	@Override
	public long getPrice(long userId, int type) {
		UserDO me = userDao.get(userId);
		if(null == me) {
			throw new RuntimeException("用户不存在");
		}

		Integer agentLevel = me.getAgentLevel();
		agentLevel = agentLevel == null ? 0 : agentLevel;
		//代理级别 1:代理 2:初级合伙人 3:中级合伙人 4:高级合伙人 5:特级合伙人
		long price = 0;
		switch (agentLevel) {
			case 0 :
				if (ProductType.HEI_MEI.getValue().equals(type)) {
					price = distConfigValueService.getMEMBER_HEI_MEI_PRICE();
				}else{
					price = distConfigValueService.getMEMBER_PRICE();
				}
				break;
			case 1:
				if (ProductType.HEI_MEI.getValue().equals(type)) {
					price = distConfigValueService.getPROXY_HEI_MEI_PRICE();
				}else{
					price = distConfigValueService.getPROXY_PRICE();
				}

				break;
			case 2:
				if (ProductType.HEI_MEI.getValue().equals(type)) {
					price = distConfigValueService.getJUNIOR_PARTNER_HEI_MEI_PRICE();
				}else{
					price = distConfigValueService.getJUNIOR_PARTNER_PRICE();
				}
				break;
			case 3:
				if (ProductType.HEI_MEI.getValue().equals(type)) {
					price = distConfigValueService.getINTERMEDIATE_PARTNER_HEI_MEI_PRICE();
				}else{
					price = distConfigValueService.getINTERMEDIATE_PARTNER_PRICE();
				}
				break;
			case 4:
				if (ProductType.HEI_MEI.getValue().equals(type)) {
					price = distConfigValueService.getSENIOR_PARTNER_HEI_MEI_PRICE();
				}else{
					price = distConfigValueService.getSENIOR_PARTNER_PRICE();
				}

				break;
			case 5:
				if (ProductType.HEI_MEI.getValue().equals(type)) {
					price = distConfigValueService.getCOFOUNDER_HEI_MEI_PRICE();
				}else{
					price = distConfigValueService.getCOFOUNDER_PRICE();
				}
				break;
			case 6:
				price = 0;
				break;
				default:
					throw new BizException("代理级别（"+agentLevel+"）价格未配置", 1001);
		}
		return price;
	}

	@Override
	public List<OrderDO> unpaidOrderList(Long userId) {
		OrderDOExample example = new OrderDOExample();
		byte defaultStatus = 0;
		example.createCriteria().andUserIdEqualTo(userId).andOrderStatusEqualTo(defaultStatus);
		example.setOrderByClause("id desc");
		List<OrderDO> orderDOs = orderDOMapper.selectByExample(example);
		return orderDOs;
	}

	@Override
	public List<OrderDO> myOrderList(Long userId) {
		OrderDOExample example = new OrderDOExample();
		example.createCriteria().andUserIdEqualTo(userId);
		example.setOrderByClause("id desc");
		List<OrderDO> orderDOs = orderDOMapper.selectByExample(example);
		for(OrderDO orderDo: orderDOs) {
			if(orderDo.getExpirationTime()!= null
					&& orderDo.getExpirationTime().before(DateTime.now().toDate()) ) {
				orderDo.setIsExp(1);
			}
		}
		return orderDOs;
	}

	@Override
	public List<OrderDO> memberOrderList(Long userId) {
		OrderDOExample example = new OrderDOExample();
		example.createCriteria().andCreateUserIdEqualTo(userId);
		example.setOrderByClause("id desc");
		List<OrderDO> orderDOs = orderDOMapper.selectByExample(example);
		for(OrderDO orderDo: orderDOs) {
			if(orderDo.getExpirationTime()!= null
					&& orderDo.getExpirationTime().before(DateTime.now().toDate()) ) {
				orderDo.setIsExp(1);
			}
		}
		return orderDOs;
	}

	@Override
	public List<OrderDO> deliverOrderList(Long userId) {
		List<OrderDO> orderDOs = orderDOMapper.getMyDeliverOrder(userId);
		for(OrderDO orderDo: orderDOs) {
			if(orderDo.getExpirationTime()!= null
					&& orderDo.getExpirationTime().before(DateTime.now().toDate()) ) {
				orderDo.setIsExp(1);
			}
		}
		return orderDOs;
	}

	@Override
	public OrderDO getOrderById(Integer orderId) {
		OrderDO orderDO = orderDOMapper.selectByPrimaryKey(orderId);
		return orderDO;
	}

	@Override
	public OrderDO getOrderByNo(String orderNo) {
		OrderDO orderDO = orderDOMapper.getOrderByOrderNo(orderNo);
		return orderDO;
	}

	@Override
	public Integer updateOrderToPaid(String orderNo,String payChannel) {
		OrderDO orderDO = orderDOMapper.getOrderByOrderNo(orderNo);
		if(orderDO!=null){
			if(orderDO.getIsFr()!=null && orderDO.getIsFr()>0){
				//已经分润
				return 0;
			}
			orderDO.setPayChannel("现金积分支付");
			orderDOMapper.updateOrderPaid(orderNo,payChannel);
			pointsService.splitPointAfterOrderSuccess(orderDO.getId());
		}else{
			return 0;
		}
		return 1;
	}

	@Override
	public Integer updateOrderNo(Integer orderId) {

		return orderDOMapper.updateOrderNo(orderId);
	}

	@Override
	public Integer updateOrderAmount(String orderNo) {

		return orderDOMapper.updateOrderAmount(orderNo);
	}

	@Override
	public List<OrderDO> queryOrder(Integer offset, Integer limit, String orderNo,String mobile,String receiver, Integer status) {
		return orderDOMapper.queryOrder(offset,limit,orderNo,status,mobile,receiver);
	}

	@Override
	public int countOrder(String orderNo,Integer status,String mobile,String receiver) {
		return orderDOMapper.countOrder(orderNo,status,mobile,receiver);
	}

	@Override
	public int updateStatus(Integer id, Integer status) {
		return orderDOMapper.updateStatus(id,status);
	}

	@Override
	public List<WithdrawDO> queryWithdraw(Integer offset, Integer limit, Integer status, Long userId) {
		return withdrawDOMapper.queryWithdraw(offset,limit,status,userId);
	}

	@Override
	public int countWithdraw(Integer status, Long userId) {
		return withdrawDOMapper.countWithdraw(status,userId);
	}

	@Override
	public int updateWithdrawStatus(Integer id, Integer status) {
		return withdrawDOMapper.updateStatus(id,status);
	}

	/**
	 * 现金积分支付
	 * @param payUser
	 * @param orderDO
	 * @return
	 */
	@Override
	@Transactional
	public int cashPay(UserDO payUser, OrderDO orderDO) {
		synchronized (orderDO.getOrderNo()) {
			//判断积分是否够用
			Long payUserId = payUser.getUserId();
			Integer cashbanlance = pointsService.cashPointsTotal(payUserId); //积分余额
			ThrowUtils.throwCondition(cashbanlance==null || cashbanlance < orderDO.getAmount(),100,"现金积分余额不足");
			//扣减积分
			//分配第一层现金积分
			CashPointsDO firstCashPointsDO = new CashPointsDO();
			firstCashPointsDO.setAmount(-orderDO.getAmount());
			firstCashPointsDO.setCreateTime(new Date());
			firstCashPointsDO.setLastModifyTime(new Date());
			firstCashPointsDO.setType(PointTradeType.CASH_PAY); //TODO 类型
			firstCashPointsDO.setRemark("现金积分支付【userId="+payUserId+"】支付orderNo="+orderDO.getOrderNo());
			firstCashPointsDO.setServiceCharge(0);//TODO 手续费,只有提现的时候有手续费
			firstCashPointsDO.setUserId(payUserId);
			int m = cashPointsDOMapper.insertSelective(firstCashPointsDO);
			ThrowUtils.throwCondition(m<=0,100,"支付失败");
			//修改订单
			byte payed = 1; //已支付
			orderDO.setOrderStatus(payed);
			orderDO.setPayChannel("现金积分支付");
			orderDO.setPayUserName(payUser.getUsername());
			orderDO.setPayUserId(payUserId);
			orderDO.setLastModifyTime(new Date());
			orderDOMapper.updateByPrimaryKeySelective(orderDO);

			//分润
			pointsService.splitPointAfterOrderSuccess(orderDO.getId());
		}
		return 0;
	}

	@Override
	public int shopCashPay(UserDO payUser, OrderInfo orderInfo) {
		//判断积分是否够用
		Long payUserId = payUser.getUserId();
		Integer cashbanlance = pointsService.cashPointsTotal(payUserId); //积分余额
		ThrowUtils.throwCondition(cashbanlance==null || cashbanlance < orderInfo.getTotalPayee(),100,"现金积分余额不足");
		//扣减积分
		//分配第一层现金积分
		CashPointsDO firstCashPointsDO = new CashPointsDO();
		firstCashPointsDO.setAmount(-orderInfo.getTotalPayee());
		firstCashPointsDO.setCreateTime(new Date());
		firstCashPointsDO.setLastModifyTime(new Date());
		firstCashPointsDO.setType(PointTradeType.CASH_PAY); //TODO 类型
		firstCashPointsDO.setRemark("现金积分支付【userId="+payUserId+"】支付orderNo="+orderInfo.getOrderNo());
		firstCashPointsDO.setServiceCharge(0);//TODO 手续费,只有提现的时候有手续费
		firstCashPointsDO.setUserId(payUserId);
		int m = cashPointsDOMapper.insertSelective(firstCashPointsDO);
		ThrowUtils.throwCondition(m<=0,100,"支付失败");

		shopOrderService.paySuccessCallback(orderInfo.getOrderNo(),"现金积分支付", null, null);

		return 0;
	}

	@Override
	public Integer createUpgradeOrder(Long userId, Long frUserId, boolean needFr) {
		//查询产品是否存在
		UserDO me = userDao.get(userId);
		if(null == me) {
			throw new BizException("用户不存在", 10002);
		}

		long amount = getUpgradePrice(userId);
		int quantity = distConfigValueService.getOLD_MEMBER_TO_PROXY_ADD_STOCK();
		long price = amount / quantity;

		UserAddress userAddress = userAddressMapper.getUserAddressDefault(userId);
		if (userAddress == null) {
			List<UserAddress> userAddressForAll = userAddressMapper.getUserAddressForAll(userId);
			userAddress = userAddressForAll.get(0);
		}
		OrderDO order = new OrderDO();
		//订单号
		String orderNo = StringUtils.generateOrderNO("C");
		if (needFr) {
			orderNo = StringUtils.generateOrderNO("D");
			quantity = distConfigValueService.getNEW_MEMBER_TO_PROXY_ADD_STOCK();
		}
		order.setOrderNo(orderNo);

		ProductType productType = ProductType.DU_XIAO_LI;
		//订单标题
		byte defaultStatus = 0;
		order.setOrderStatus(defaultStatus);
		order.setOrderTitle("会员升级为代理");
		order.setCreateUserId(userId);//直推人
		order.setCreateTime(new Date());
		order.setUserId(userId);
		order.setProductId(productType.getProductId());
		order.setQuantity(quantity);//购买数量
		order.setSalePrice((int) price);//单价
		order.setAmount((int) amount); //总金额
		order.setProvince(userAddress.getProvince());
		order.setCity(userAddress.getCity());
		order.setDistrict(userAddress.getDistrict());
		order.setPostcode(userAddress.getPostcode());
		order.setAddress(userAddress.getAddress());
		order.setTel(userAddress.getTel());
		order.setMobile(userAddress.getMobile());
		order.setReceiver(userAddress.getName());
		order.setFrUserId(frUserId);
		order.setIsFr(0);
		//过期时间
		order.setExpirationTime(DateTime.now().plusDays(10).toDate());
		orderDOMapper.insertSelective(order);
		return order.getId();
	}

	public long getUpgradePrice(Long userId) {
		UserDO me = userDao.get(userId);
		Integer ml = me.getMemberLevel();
		long price = 0;
		if (ml == null) {
			price = distConfigValueService.getNEW_MEMBER_TO_PROXY_PRICE();
		} else if (1 == ml) {
			price = distConfigValueService.getOLD_MEMBER_TO_PROXY_PRICE();
		} else if (2 == ml) {
			price = distConfigValueService.getOLD_MEMBER_TO_PROXY_PRICE();
		} else if (3 == ml) {
			price = distConfigValueService.getOLD_MEMBER_TO_PROXY_PRICE();
		} else {
			price = distConfigValueService.getNEW_MEMBER_TO_PROXY_PRICE();
		}
		return price;
	}
}
